/**
 * 格式化预测类折线组件和柱状组件
 */

import { cloneDeep,merge } from 'lodash-es';
import { $each } from '../index';
import { processXAis, processSeriesData } from './lineAndBarFormat.js';

const kindRealChartObj = {
  forecastBar: 'yAxisRealBar',
  forecastLine: 'yAxisRealLine'
}
const kindEmptyChartObj = {
  forecastBar: 'yAxisEmptyBar',
  forecastLine: 'yAxisEmptyLine'
}

/**
 * 预测基本柱状，折线图
 * @param {*} datasets
 */
export function baseForecastBarOrLineFormat({ datasets, typeChart, extra }) {

  const { dimensions } = datasets;
  //预测天数
  const { forecastDays } = extra;
  // 多度量的时候使用的是&链接
  const { legend, xAxis } = dimensions;
  const xAxisData = processXAis(datasets);
  // 静态数据默认走legend - 颜色维度
  // 生成真实数据的series, 区分是柱状图调用还是折线图调用
  const realSeriesData = processSeriesData(datasets, {
    xData: xAxisData,
    // 这里：预测折线预测柱状有y轴字段区分，根据typeChart判断
    yAxis: dimensions[kindRealChartObj[typeChart]],
    legend,
    xAxis,
    typeChart,
    // 预测图那种图表（柱状图、折线图、柱折图）
    forecastType: kindRealChartObj[typeChart],
    dataType: 'forecast',
    // 标识是预测数据还是真实数据
    isForecastOrRealData: 'real',
    dataFormatType: 'yAxis',
  });

  const realDataObj = findSourceIndex(realSeriesData, dimensions[kindRealChartObj[typeChart]]);
  // bar-生成预测数据的series
  const emptySeriesData = processSeriesData(datasets, {
    xData: xAxisData,
    // 这里：预测折线预测柱状有y轴字段区分，根据typeChart判断
    yAxis: dimensions[kindEmptyChartObj[typeChart]],
    legend,
    xAxis,
    typeChart,
    // 预测图那种图表（柱状图、折线图、柱折图）
    forecastType: kindEmptyChartObj[typeChart],
    realYAxis: dimensions[kindRealChartObj[typeChart]],
    realDataObj,
    forecastDays,
    // 标识是预测数据还是真实数据
    isForecastOrRealData: 'forecast',
    dataFormatType: 'yAxis',
  });
  // 折线图需要拼上预测的第一条数据才能拼接起来
  if (typeChart === 'forecastLine' && realSeriesData.length && emptySeriesData.length) {
    $each(realSeriesData, (item, index) => {
      const targetIndex = realDataObj[index].index;
      item.data[targetIndex] = emptySeriesData[index].data[targetIndex];
    })
  }
  return {
    seriesData: [
      // 真实数据
      ...realSeriesData,
      // 预测数据
      ...emptySeriesData,
    ],
    xAxisData,
  };
}


/**
 * 预测柱折图
 */
export function baseForecastBarAndLineFormat({ datasets, typeChart, extra }) {
  const { dimensions } = datasets;
   //预测天数
  const { forecastDays } = extra;
  // 多度量的时候使用的是&链接
  const { legend, xAxis } = dimensions;
  const xAxisData = processXAis(datasets);
  const open = typeChart && typeChart === 'forecastBarAndLineDoubleY';
  // 静态数据默认走legend - 颜色维度
  // bar-生成真实数据的series
  const realBarSeriesData = processSeriesData(datasets, {
    xData: xAxisData,
    // 这里：预测折线预测柱状有y轴字段区分，根据typeChart判断
    yAxis: dimensions[kindRealChartObj['forecastBar']],
    legend,
    xAxis,
    typeChart,
    // 预测图那种图表（柱状图、折线图、柱折图）
    forecastType: kindRealChartObj['forecastBar'],
    dataType: 'forecast',
    componentType: 'bar',
    // 标识是预测数据还是真实数据
    isForecastOrRealData: 'real',
    dataFormatType: 'yAxis',
    open,
  });

  const realBarDataObj = findSourceIndex(realBarSeriesData, dimensions['yAxisRealBar']);
  // bar-生成预测数据的series
  const emptyBarSeriesData = processSeriesData(datasets, {
    xData: xAxisData,
    // 这里：预测折线预测柱状有y轴字段区分，根据typeChart判断
    yAxis: dimensions[kindEmptyChartObj['forecastBar']],
    legend,
    xAxis,
    typeChart,
    // 预测图那种图表（柱状图、折线图、柱折图）
    forecastType: kindEmptyChartObj['forecastBar'],
    realYAxis: dimensions['yAxisRealBar'],
    realDataObj: realBarDataObj,
    forecastDays,
    componentType: 'bar',
    // 标识是预测数据还是真实数据
    isForecastOrRealData: 'forecast',
    dataFormatType: 'yAxis',
    open,
  });

  // line-预测折线真实数据
  const realLineSeriesData = processSeriesData(datasets, {
    xData: xAxisData,
    // 这里：预测折线预测柱状有y轴字段区分，根据typeChart判断
    yAxis: dimensions['yAxisRealLine'],
    legend,
    xAxis,
    typeChart,
    // 预测图那种图表（柱状图、折线图、柱折图）
    forecastType: kindRealChartObj['forecastLine'],
    dataType: 'forecast',
    componentType: 'line',
    // 标识是预测数据还是真实数据
    isForecastOrRealData: 'real',
    dataFormatType: 'yAxis',
    open,
  });
  // 判断拖入了折线的真实数据才去调用，否则会污染柱状的预测数据
  const realLineDataObj = findSourceIndex(realLineSeriesData, dimensions['yAxisRealLine']);
  // line-预测折线预测数据
  const emptyLineSeriesData = processSeriesData(datasets, {
    xData: xAxisData,
    // 这里：预测折线预测柱状有y轴字段区分，根据typeChart判断
    yAxis: dimensions['yAxisEmptyLine'],
    legend,
    xAxis,
    typeChart,
    // 预测图那种图表（柱状图、折线图、柱折图）
    forecastType: kindEmptyChartObj['forecastLine'],
    realYAxis: dimensions['yAxisRealLine'],
    realDataObj: realLineDataObj,
    forecastDays,
    componentType: 'line',
    // 标识是预测数据还是真实数据
    isForecastOrRealData: 'forecast',
    dataFormatType: 'yAxis',
    open,
  });
  // 折线图需要拼上预测的第一条数据才能拼接起来
  if (emptyLineSeriesData.length && realLineSeriesData.length) {
    $each(realLineSeriesData, (item, index) => {
      const targetIndex = realLineDataObj[index].index;
      //真实数据
      item.data[targetIndex] = merge({},emptyLineSeriesData[index].data[targetIndex], {isForecastOrRealData: 'real', isJoint: true});
    })
  }
  return {
    seriesData: [
      // 真实柱状图数据
      ...realBarSeriesData,
      // 预测柱状图数据
      ...emptyBarSeriesData,
      // 真实折线图数据
      ...realLineSeriesData,
      // 预测折线图数据
      ...emptyLineSeriesData,
    ],
    xAxisData,
  };
}


function findSourceIndex(realSeriesData, legendYAxis) {
  // 找到item最后一个值的索引，记录传给预测数据调用的Series方法
  const realDataObj = [];
  $each(realSeriesData, (item, keyIndex) => {
    const obj = {
      key: keyIndex,
      legendYAxis,
      index: ''
    }
    // 倒着找不是-的，是真实数据的索引位置
    for (let k = item.data.length - 1; k >= 0; k--) {
      /**
       * 存在情况
       * 1.真实数据都有值，不存在占位, 约定realDataIndex是item.length
       * 2.真实数据都没值，全是占位，约定realDataIndex是0
       * 3.剩余的通属于补全的，正常的索引位置
       */
      // 当前项为-，但当前项的下一项非-，即为有数据,必须存在下一项
      if (item.data[k].value === '-' && item.data[k - 1] && item.data[k - 1].value !== '-') {
        obj.index = k;
        break;
      }
      // 或者是-为最后一项,不存在下一项
      if (item.data[k].value === '-' && !item.data[k - 1]) {
        obj.index = k;
        break;
      }
    }
    realDataObj.push(obj);
  });
  return realDataObj;
}
